package com.android.gl2jni.filter;

import android.content.Context;

/**
 * Create time: 2018/9/27.
 */
public class GlitchFilterProgram extends TextureFilterProgram {
  private static final String FRAGMENT =
      "#extension GL_OES_EGL_image_external : require\n" +
      " precision highp float;\n" +
      " varying vec2 vTextureCoord;\n" +
      " uniform samplerExternalOES uTexture;\n" +
      " uniform vec2 uScanLineJitter;//displacement threshold\n" +
      " uniform float uColorDrift;\n" +
      " uniform float uGlobalTime;\n" +
      "float nrand(in float x, in float y)\n" +
      "{\n" +
      "     return fract(sin(dot(vec2(x, y), vec2(12.9898, 78.233))) * 43758.5453);\n" +
      "}\n" +
      "void main(){\n" +
      "    float u = vTextureCoord.x;\n" +
      "    float v = vTextureCoord.y;\n" +
      "    float jitter = nrand(v,0.0) * 2.0 - 1.0;//这里得到一个-1到1的数\n" +
      "    float drift = uColorDrift;\n" +
      "    //step是gl自带函数，意思是，如果第一个参数大于第二个参数，那么返回0，否则返回1\n" +
      "    float offsetParam = step(uScanLineJitter.y,abs(jitter));\n" +
      "    jitter = jitter * offsetParam * uScanLineJitter.x;\n" +
      "    vec4 color1 = texture2D(uTexture,fract(vec2(u + jitter,v)));\n" +
      "    vec4 color2 = texture2D(uTexture,fract(vec2(u + jitter + v*drift,v)));\n" +
      "    gl_FragColor = vec4(color1.r,color2.g,color1.b,1.0);\n" +
      "}";

  private int mScanLineJitterLoc;
  private int mColorDriftLoc;
  private int mGlobalTimeLoc;

  private long mStartTime;

  private int mFrames = 0;

  private int mMaxFrames = 8;

  private float[] mDriftSequence = new float[]{0f, 0.03f, 0.032f, 0.035f, 0.03f, 0.032f, 0.031f, 0.029f, 0.025f};

  private float[] mJitterSequence = new float[]{0f, 0.03f, 0.01f, 0.02f, 0.05f, 0.055f, 0.03f, 0.02f, 0.025f};

  private float[] mThreshHoldSequence = new float[]{1.0f, 0.965f, 0.9f, 0.9f, 0.9f, 0.6f, 0.8f, 0.5f, 0.5f};

  public GlitchFilterProgram(Context context) {
    super(context, ProgramType.TEXTURE_EXT);
  }

  @Override
  protected String getFragmentShaderSourceEXT() {
    return FRAGMENT;
  }

  @Override
  protected void initProgram() {
    super.initProgram();
    mScanLineJitterLoc = getUniformLocation("uScanLineJitter");
    mColorDriftLoc = getUniformLocation("uColorDrift");
    mGlobalTimeLoc = getUniformLocation("uGlobalTime");
  }

  @Override
  protected void onDraw(int firstVertex, int vertexCount) {
    long time = System.currentTimeMillis();
    if (mStartTime == 0) {
      mStartTime = time;
    }
    setFloat(mGlobalTimeLoc, mFrames);
    mStartTime = time;

    float slDisplacement = mJitterSequence[mFrames];
    float slThreshold = mThreshHoldSequence[mFrames];
    float drift = mDriftSequence[mFrames];
    mFrames++;
    if (mFrames > mMaxFrames) {
      mFrames = 0;
    }
    setFloatVec2(mScanLineJitterLoc, new float[]{slDisplacement, slThreshold});
    setFloat(mColorDriftLoc, drift);
    super.onDraw(firstVertex, vertexCount);
  }
}
